# coding=utf8
from pyjvm.instructions import BytecodeReader, get_instruction
from pyjvm.runtime.thread import Thread, Frame


def interpret(thread: Thread, print_inst=False):
    reader = BytecodeReader(b'')

    while thread.is_not_empty_frame():
        frame: Frame = thread.current_frame()
        pc = frame.next_pc
        thread.pc = pc
        reader.reset(frame.method.code, pc)
        if reader.readable():
            op_code = reader.uint8()
            instruction = get_instruction(op_code)
            if instruction is None:
                print('Unsupported op code:', op_code)
                break
            method = frame.method

            instruction.fetch_operands(reader)
            frame.set_next_pc(reader.pc())
            try:
                instruction.record = None
                instruction.execute(frame)
            except Exception as debug:
                print_inst = True
                raise debug
            finally:
                if print_inst:
                    print('level', thread.frame_len(), pc, method.klass.name, method.name, method.descriptor,
                          instruction.__class__.__name__)
                if instruction.record is not None and print_inst:
                    print(instruction.record)
        else:
            continue


__all__ = ['interpret']
